﻿using System;
using System.Collections.Generic;
using System.Transactions;
using System.Web;
using AcountingService.CommonClass;
using AcountingService.DataTransferObjectMapper;
using AcountingService.MessageBase;
using AcountingService.Messages;
using AcountingService.Messages.Dictionary;
using AcountingService.Messages.Report;
using AcountingService.Messages.Voucher;
using BusinessObjects.BussinessVoucher;
using DataObjects;
using DataObjects.Shared;
using DataObjects.StandartInterfaces;
using DataObjects.StandartInterfaces.Dictionary;
using DataObjects.StandartInterfaces.Report;
using DataObjects.StandartInterfaces.Voucher;

namespace AcountingService
{
    // NOTE: You can use the "Rename" command on the "Refactor" menu to change the class name "ActionAccountingService" in code, svc and config file together.
    // NOTE: In order to launch WCF Test Client for testing this service, please select ActionAccountingService.svc or ActionAccountingService.svc.cs at the Solution Explorer and start debugging.
    /// <summary>
    /// ActionAccountingService service
    /// </summary>
    public class ActionAccountingService : IActionAccountingService
    {
        //Create static data access objects
        private static readonly IEmployTest EmployTestDao = DataAccess.EmployTestDao;
        private static readonly ICustomerDao CustomerDao = DataAccess.CustomerDao;
        private static readonly IDepartmentDao DepartmentDao = DataAccess.DepartmentDao;

        private static readonly IAutoNumberDao AutoNumberDao = DataAccess.AutoNumberDao;
        private static readonly IUnitDao UnitDao = DataAccess.UnitDao;
        private static readonly IJournalEntryAccountDao JournalEntryAccountDao = DataAccess.JournalEntryAccountDao;
        private static readonly ITaxTransDao TaxTransDao = DataAccess.TaxTransDao;


        private static readonly IAccountBalanceDao AccountBalanceDao = DataAccess.AccountBalanceDao;

        private static readonly IVendorDao VendorDao = DataAccess.VendorDao;
        private static readonly IRefTypeDao RefTypeDao = DataAccess.RefTypeDao;
        private static readonly IVoucherTypeDao VoucherTypeDao = DataAccess.VoucherTypeDao;
        private static readonly IFixedAssetDao FixedAssetDao = DataAccess.FixedAssetDao;
        private static readonly IFixedAssetCategoryDao FixedAssetCategoryDao = DataAccess.FixedAssetCategoryDao;
        private static readonly IAccountDao AccountDao = DataAccess.AccountDao;
        private static readonly IStockDao StockDao = DataAccess.StockDao;
        private static readonly IAutoBusinessDao AutoBusinessDao = DataAccess.AutoBusinessDao;
        private static readonly IInventoryItemDao InventoryItemDao = DataAccess.InventoryItemDao;
        private static readonly IDbOptionDao DbOptionDao = DataAccess.DbOptionDao;
        private static readonly IItemTransactionDao ItemTransactionDao = DataAccess.ItemTransactionDao;

        private static readonly IItemTransactionDetailDao ItemTransactionDetailDao = DataAccess.ItemTransactionDetailDao;

        private static readonly IReportListDao ReportListDao = DataAccess.ReportListDao;
        private static readonly IReportGroupDao ReportGroupDao = DataAccess.ReportGroupDao;


        // Session state variables  >
        /// <summary>
        /// The _access token
        /// </summary>
        private static string _accessToken;
        /// <summary>
        /// The _unit identifier
        /// </summary>
        public static long _unitId = 1;
        //  {
        //get
        //{
        //    var unitIdSession = HttpContext.Current.Session["FA-BigTime.UnitId"];
        //    return unitIdSession == null ? 0 : (long)unitIdSession;
        //}
        //set
        //{
        //    HttpContext.Current.Session["FA-BigTime.UnitId"] = value;
        //}
        //   }
        /// <summary>
        /// Gets or sets the name of the _unit.
        /// </summary>
        /// <value>
        /// The name of the _unit.
        /// </value>
        public static string _unitName
        {
            get
            {
                var unitNameSession = HttpContext.Current.Session["FA-BigTime.UnitName"];
                return unitNameSession == null ? "" : unitNameSession.ToString();
            }
            set
            {
                HttpContext.Current.Session["FA-BigTime.UnitName"] = value;
            }
        }
        /// <summary>
        /// Gets or sets the user identifier.
        /// </summary>
        /// <value>
        /// The user identifier.
        /// </value>
        public static string userId
        {
            get
            {
                var unitNameSession = HttpContext.Current.Session["FA-BigTime.UserId"];
                return unitNameSession == null ? "" : unitNameSession.ToString();
            }
            set
            {
                HttpContext.Current.Session["FA-BigTime.UserId"] = value;
            }
        }
        /// <summary>
        /// Does the work.
        /// </summary>
        public void DoWork()
        {
        }

        /// <summary>
        /// Gets the token.
        /// </summary>
        /// <param name="request">The request.</param>
        /// <returns></returns>
        public TokenResponse GetToken(TokenRequest request)
        {
            var response = new TokenResponse(request.RequestId);

            // Validate client tag only
            if (!ValidRequest(request, response, Validate.ClientTag))
                return response;

            // Note: these are session based and expire when session expires.
            _accessToken = Guid.NewGuid().ToString();
            response.AccessToken = _accessToken;
            return response;
        }

        #region Units
        public UnitResponse GetUnits(UnitRequest request)
        {
            var response = new UnitResponse(request.RequestId);
            var criteria = request.Criteria;

            if (!ValidRequest(request, response, Validate.All))
                return response;
            if (request.LoadOptions != null)
            {
                if (request.LoadOptions.Contains("Units")) //get list of BudgetSourcesProperty
                {
                    if ((OptionType.IsUnit & request.Options) == OptionType.IsUnit) //get by unit & paging || non-paging
                    {
                        if ((OptionType.IsPaging & request.Options) == OptionType.IsPaging)
                        {
                            if (_unitId==1) 
                            {
                                var units = UnitDao.GetPaged(_unitId.AsInt(), request.CurrentPage);
                                response.Units = AcountingService.DataTransferObjectMapper.Mapper.ToDataTransferObjects(units);
  
                            }
                        }
                    }
                    else //get all
                    {
                        if ((request.Options & request.Options) == OptionType.IsActive)
                        {
                            var units = UnitDao.GetUnits(request.IsActive);
                            response.Units = AcountingService.DataTransferObjectMapper.Mapper.ToDataTransferObjects(units);
                        }
                        else
                        {
                            var units = UnitDao.GetUnits();
                            response.Units = AcountingService.DataTransferObjectMapper.Mapper.ToDataTransferObjects(units);
                        }
                    }
                }

                if (request.LoadOptions.Contains("Unit")) //get budgetSource by id
                {
                    var unit = UnitDao.GetUnit(criteria.UnitId.AsInt());
                    response.Unit = AcountingService.DataTransferObjectMapper.Mapper.ToDataTransferObject(unit);
                }
                if (request.LoadOptions.Contains("TotalPage"))
                {
                    var totalPage = UnitDao.GetPageSize();
                    response.TotalPage = totalPage;
                }
            }
            return response;
        }

        public UnitResponse SetUnits(UnitRequest request)
        {
            var response = new UnitResponse(request.RequestId);
            string errorMessage = null;

            // Validate client tag, access token, and user credentials
            if (!ValidRequest(request, response, Validate.All))
                return response;

            // Transform customer data transfer object to customer business object
            var unit = Mapper.FromDataTransferObject(request.Unit);

            // Validate customer business rules
            if (request.Action != "Delete")
            {
                if (!unit.Validate())
                {
                    response.Acknowledge = AcknowledgeType.Failure;

                    foreach (var error in unit.ValidationErrors)
                        response.Message += error + Environment.NewLine;

                    return response;
                }
            }
            try
            {
                switch (request.Action)
                {
                    case "Create":
                        unit.UnitId =(int) UnitDao.GetSequence();
                        errorMessage = UnitDao.InsertUnit(unit);
                        if (errorMessage != null)
                        {
                            response.Acknowledge = AcknowledgeType.Failure;
                            response.Message = errorMessage;
                            return response;
                        }
                        errorMessage = DbOptionDao.InsertDbOptionByUnit(unit.UnitId.AsInt());
                        if (errorMessage != null)
                        {
                            response.Acknowledge = AcknowledgeType.Failure;
                            response.Message = errorMessage;
                            return response;
                        }
                        errorMessage = AccountDao.InsertAccountByUnit(unit.UnitId.AsInt());
                        if (errorMessage != null)
                        {
                            response.Acknowledge = AcknowledgeType.Failure;
                            response.Message = errorMessage;
                            return response;
                        }
                        break;
                    case "Update":
                        errorMessage = UnitDao.UpdateUnit(unit);
                        break;
                    case "Delete":
                        var criteria = request.Criteria;
                        var unitDelete = UnitDao.GetUnit((int)criteria.UnitId);
                        if (unitDelete == null)
                        {
                            response.Acknowledge = AcknowledgeType.Failure;
                            response.Message = "Không thể xóa !Dữ liệu không còn tồn tại trong hệ thống !";
                        }
                        else
                        {
                            //check child
                            var child = UnitDao.GetUnitsByParentId((int)criteria.UnitId).Count;
                            if (child == 0)
                            {
                                response.Acknowledge = AcknowledgeType.Success;
                                errorMessage = UnitDao.DeleteUnit(unitDelete);
                            }
                            else
                            {
                                response.Acknowledge = AcknowledgeType.Failure;
                                response.Message = "Không thể xóa !Đơn vị đã có đơn vị cấp dưới !";
                            }
                        }
                        break;
                }
                if (errorMessage == null)
                {
                    response.Acknowledge = AcknowledgeType.Success;
                    response.Unit = Mapper.ToDataTransferObject(unit);
                }
                else
                {
                    response.Acknowledge = AcknowledgeType.Failure;
                    response.Message = errorMessage;
                }
            }
            catch (Exception ex)
            {
                response.Acknowledge = AcknowledgeType.Failure;
                response.Message = ex.Message;
            }

            return response;
        }
        #endregion

        /// <summary>
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        public EmployTestResponse GetEmployTests(EmployTestRequest request)
        {
            var response = new EmployTestResponse(request.RequestId);
            var criteria = request.Criteria;

            if (!ValidRequest(request, response, Validate.All))
                return response;

            if (request.LoadOptions != null)
            {
                if (request.LoadOptions.Contains("EmployTests"))
                {
                    if ((OptionType.IsUnit & request.Options) == OptionType.IsUnit)
                    {
                        if ((OptionType.IsPaging & request.Options) == OptionType.IsPaging)
                        {
                            var employTests = EmployTestDao.GetPaged(_unitId.AsInt(), request.CurrentPage);
                            response.EmployTests = AcountingService.DataTransferObjectMapper.Mapper.ToDataTransferObjects(employTests);
                        }
                        else
                        {
                            if ((OptionType.IsActive & request.Options) == OptionType.IsActive)
                            {
                                //    var employTests = EmployTestDao.GetEmployTestsByUnit(_unitId.AsInt());
                                //    response.EmployTests = Mapper.ToDataTransferObjects(employTests);
                            }
                        }
                    }
                }
                if (request.LoadOptions.Contains("EmployTest")) //get EmployTest by id
                {
                    var employTest = EmployTestDao.GetEmployTest(criteria.EmployTestId);
                    response.EmployTest = AcountingService.DataTransferObjectMapper.Mapper.ToDataTransferObject(employTest);
                }

                if (request.LoadOptions.Contains(("TotalPage")))
                {
                    var totalPage = EmployTestDao.GetPageSize(_unitId.AsInt());
                    response.TotalPage = totalPage;
                }
            }
            return response;
        }

        /// <summary>
        /// EmployTest
        /// Set (add, update, delete) customer value.
        /// </summary>
        /// <param name="request">EmployTest request message.</param>
        /// <returns>
        /// EmployTest response message.
        /// </returns>
        public EmployTestResponse SetEmployTests(EmployTestRequest request)
        {
            var response = new EmployTestResponse(request.RequestId);
            string errorMessage = null;

            // Validate client tag, access token, and user credentials
            if (!ValidRequest(request, response, Validate.All))
                return response;
            if (request.EmployTest != null)
            {
                //request.EmployTest.UnitId = _unitId;
                //request.EmployTest.IsSystem = false;
            }
            // Transform customer data transfer object to customer business object
            var employTest = AcountingService.DataTransferObjectMapper.Mapper.FromDataTransferObject(request.EmployTest);

            // Validate customer business rules
            if (request.Action != "Delete")
            {
                if (!employTest.Validate())
                {
                    response.Acknowledge = AcknowledgeType.Failure;

                    foreach (var error in employTest.ValidationErrors)
                        response.Message += error + Environment.NewLine;

                    return response;
                }
            }

            try
            {
                switch (request.Action)
                {
                    case "Create":
                        errorMessage = EmployTestDao.InsertEmployTest(employTest);
                        break;
                    case "Update":
                        errorMessage = EmployTestDao.UpdateEmployTest(employTest);
                        break;
                    case "Delete":
                        var criteria = request.Criteria;
                        var employForDelete = EmployTestDao.GetEmployTest(criteria.EmployTestId);
                        errorMessage = EmployTestDao.DeleteEmployTest(employForDelete);
                        break;
                }
                if (errorMessage == null)
                {
                    response.Acknowledge = AcknowledgeType.Success;
                    response.EmployTest = AcountingService.DataTransferObjectMapper.Mapper.ToDataTransferObject(employTest);
                }
                else
                {
                    response.Acknowledge = AcknowledgeType.Failure;
                    response.Message = errorMessage;
                }
            }
            catch (Exception ex)
            {
                response.Acknowledge = AcknowledgeType.Failure;
                response.Message = ex.Message;
            }
            return response;
        }


        #region Accounts
        /// <summary>
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        public AccountResponse GetAccounts(AccountRequest request)
        {
            var response = new AccountResponse(request.RequestId);
            var criteria = request.Criteria;

            if (!ValidRequest(request, response, Validate.All))
                return response;

            if (request.LoadOptions.Contains("Accounts")) //get list of BudgetSourcesProperty
            {
                if ((OptionType.IsUnit & request.Options) == OptionType.IsUnit) //get by unit & paging || non-paging
                {
                    if ((OptionType.IsPaging & request.Options) == OptionType.IsPaging)
                    {
                        var accounts = AccountDao.GetPaged(_unitId.AsInt(), request.CurrentPage);
                        var totalPage = AccountDao.GetPageSize(_unitId.AsInt());
                        response.TotalPage = totalPage;
                        response.Accounts = AcountingService.DataTransferObjectMapper.Mapper.ToDataTransferObjects(accounts);
                    }
                    else
                    {
                        if (request.LoadOptions.Contains("ForComboTree"))
                        {
                            var accounts = AccountDao.GetAccountsForComboTree(_unitId.AsInt());
                            response.Accounts = AcountingService.DataTransferObjectMapper.Mapper.ToDataTransferObjects(accounts);
                        }
                        else
                        {
                            var accounts = AccountDao.GetAccountsByUnit(_unitId.AsInt());
                            response.Accounts = Mapper.ToDataTransferObjects(accounts);
                        }
                    }
                }

            }

            if (request.LoadOptions.Contains("Account")) //get budgetSource by id
            {
                var account =  AccountDao.GetAccount(criteria.AccountId);
                response.Account = AcountingService.DataTransferObjectMapper.Mapper.ToDataTransferObject(account);
            }
            if (request.LoadOptions.Contains("InventoryItem"))
            {
                var accounts = AccountDao.GetAccountsForIsInventoryItem(_unitId.AsInt());
                response.Accounts = AcountingService.DataTransferObjectMapper.Mapper.ToDataTransferObjects(accounts);              
            }

            if (request.LoadOptions.Contains("Tax"))
            {
                var accounts = AccountDao.GetAccountsForIsTax(_unitId.AsInt());
                response.Accounts = AcountingService.DataTransferObjectMapper.Mapper.ToDataTransferObjects(accounts);
            }

            if (request.LoadOptions.Contains("Fixedasset"))
            {
                var accounts = AccountDao.GetAccountsForIsFixedasset(_unitId.AsInt());
                response.Accounts = AcountingService.DataTransferObjectMapper.Mapper.ToDataTransferObjects(accounts);
            }

            if (request.LoadOptions.Contains("AccountingObject"))
            {
                var accounts = AccountDao.GetAccountsForIsAccountingObject(_unitId.AsInt());
                response.Accounts = AcountingService.DataTransferObjectMapper.Mapper.ToDataTransferObjects(accounts);
            }


            if (request.LoadOptions.Contains(("TotalPage")))
            {
                var totalPage = AccountDao.GetPageSize(_unitId.AsInt());
                if (totalPage == 0)
                {
                    totalPage = 1;
                }
                response.TotalPage = totalPage;
            }
            return response;
        }
        /// <summary>
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        public AccountResponse SetAccounts(AccountRequest request)
        {

            var response = new AccountResponse(request.RequestId);
            string errorMessage = null;

            // Validate client tag, access token, and user credentials
            if (!ValidRequest(request, response, Validate.All))
                return response;
            if (request.Account != null)
            {
                request.Account.UnitId = _unitId;
            }
            // Transform customer data transfer object to customer business object
            var account = AcountingService.DataTransferObjectMapper.Mapper.FromDataTransferObject(request.Account);

            // Validate customer business rules
            if (request.Action != "Delete")
            {
                if (!account.Validate())
                {
                    response.Acknowledge = AcknowledgeType.Failure;

                    foreach (var error in account.ValidationErrors)
                        response.Message += error + Environment.NewLine;

                    return response;
                }
            }
            try
            {
                switch (request.Action)
                {
                    case "Create":
                        errorMessage = AccountDao.InsertAccount(account);
                        break;
                    case "Update":
                        errorMessage = AccountDao.UpdateAccount(account);
                        break;
                    case "Delete":
                        var criteria = request.Criteria;
                        var accountDelete =
                            AccountDao.GetAccount(criteria.AccountId);
                        if (accountDelete == null)
                        {
                            response.Acknowledge = AcknowledgeType.Failure;
                            response.Message = "Không thể xóa ! Dữ liệu không còn tồn tại trong hệ thống !";
                            return response;
                        }
                        //check child
                        var child = AccountDao.GetAccountsByParent(criteria.AccountId).Count;
                        if (child == 0)
                        {
                            response.Acknowledge = AcknowledgeType.Success;
                            errorMessage =
                                AccountDao.DeleteAccount(accountDelete);
                        }
                        else
                        {
                            response.Acknowledge = AcknowledgeType.Failure;
                            response.Message = "Không thể xóa ! Nhóm TK đã có TK con !";
                            return response;
                        }
                        break;
                }
                if (errorMessage == null)
                {
                    response.Acknowledge = AcknowledgeType.Success;
                    response.Account = AcountingService.DataTransferObjectMapper.Mapper.ToDataTransferObject(account);
                }
                else
                {
                    response.Acknowledge = AcknowledgeType.Failure;
                    response.Message = errorMessage;
                }
            }
            catch (Exception ex)
            {
                response.Acknowledge = AcknowledgeType.Failure;
                response.Message = ex.Message;
            }

            return response;
        }
        #endregion

        /// <summary>
        /// Validate 3 security levels for a request: ClientTag, AccessToken, and User Credentials
        /// </summary>
        /// <param name="request">The request message.</param>
        /// <param name="response">The response message.</param>
        /// <param name="validate">The validation that needs to take place.</param>
        /// <returns></returns>
        private bool ValidRequest(RequestBase request, ResponseBase response, Validate validate)
        {
            // Validate Client Tag. 
            // Hardcoded here. In production this should query a 'client' table in a database.
            if ((Validate.ClientTag & validate) == Validate.ClientTag)
            {
                if (request.ClientTag != "ABC123")
                {
                    response.Acknowledge = AcknowledgeType.Failure;
                    response.Message = "Unknown Client Tag";
                    return false;
                }
            }
            if ((Validate.UnitId & validate) == Validate.AccessToken)
            {
                if (_accessToken != request.AccessToken)
                {
                    response.Acknowledge = AcknowledgeType.Failure;
                    response.Message = "Please login and provide unit before accessing these methods";
                    return false;
                }
            }
            return true;
        }
        /// <summary>
        /// Validation options enum. Used in validation of messages.
        /// </summary>
        [Flags]
        private enum Validate
        {
            /// <summary>
            /// The client tag
            /// </summary>
            ClientTag = 0x0001,
            /// <summary>
            /// The access token
            /// </summary>
            AccessToken = 0x0002,
            /// <summary>
            /// The user credentials
            /// </summary>
            UserCredentials = 0x0004,
            /// <summary>
            /// The unit identifier
            /// </summary>
            UnitId = 0x0008,
            /// <summary>
            /// All
            /// </summary>
            All = ClientTag | AccessToken | UserCredentials | UnitId
        }

        #region ItemTransactions
        public ItemTransactionResponse GetItemTransactions(ItemTransactionRequest request)
        {
            var response = new ItemTransactionResponse(request.RequestId);
            var criteria = request.Criteria;

            //if (!ValidRequest(request, response, Validate.All))
            //    return response;

            if (request.LoadOptions.Contains("ItemTransactions")) //get list of BudgetSourcesProperty
            {
                if ((OptionType.IsUnit & request.Options) == OptionType.IsUnit) //get by unit & paging || non-paging
                {
                    if ((OptionType.IsPaging & request.Options) == OptionType.IsPaging)
                    {
                        var itemTransactions = ItemTransactionDao.GetPaged(_unitId.AsInt(), request.RefType, request.CurrentPage);
                        var totalPage = ItemTransactionDao.GetPageSize(_unitId.AsInt(), request.RefType);
                        response.TotalPage = totalPage;
                        response.ItemTransactions = DataTransferObjectMapper.Voucher.Mapper.ToDataTransferObjects(itemTransactions);
                    }
                    //else
                    //{
                    //    var itemTransactions = ItemTransactionDao.GetItemTransactionsByUnit(_unitId.AsInt());
                    //    response.ItemTransaction = Mapper.ToDataTransferObjects(itemTransactions);
                    //}
                }
                //else //get all
                //{
                //    var itemTransactions = ItemTransactionDao.GetItemTransactions();
                //    response.ItemTransactions = Mapper.ToDataTransferObjects(itemTransactions);
                //}
            }

            if (request.LoadOptions.Contains("ItemTransaction")) //get budgetSource by id
            {
                var itemTransaction = ItemTransactionDao.GetItemTransaction(criteria.ItemTransactionId);
                response.ItemTransaction = DataTransferObjectMapper.Voucher.Mapper.ToDataTransferObject(itemTransaction);
                if ((OptionType.IsDetail & request.Options) == OptionType.IsDetail)
                {
                    var itemTransactions = ItemTransactionDetailDao.GetItemTransactionDetailsByItemTransaction(criteria.ItemTransactionId);
                  //  response.ItemTransaction.ItemTransactionDetails = AcountingService.DataTransferObjectMapper.Voucher.Mapper.ToDataTransferObjects(itemTransactions);
                    response.ItemTransactionDetails = AcountingService.DataTransferObjectMapper.Voucher.Mapper.ToDataTransferObjects(itemTransactions);
                }
            }

            if (request.LoadOptions.Contains(("TotalPage")))
            {
                var totalPage = ItemTransactionDao.GetPageSize(_unitId.AsInt(), request.RefType);
                if (totalPage == 0)
                {
                    totalPage = 1;
                }
                response.TotalPage = totalPage;
            }
            return response;
        }

        public ItemTransactionResponse SetItemTransactions(ItemTransactionRequest request)
        {
            var response = new ItemTransactionResponse(request.RequestId);
            IList<ItemTransactionDetail> itemTransactionDetails = new List<ItemTransactionDetail>();
            string errorMessage = null;
            // Validate client tag, access token, and user credentials
            //if (!ValidRequest(request, response, Validate.All))
            //    return response;
            if (request.ItemTransaction != null)
            {
                request.ItemTransaction.UnitId = _unitId;
             //   request.ItemTransaction.RefTypeId = 103;
            }
            // Transform customer data transfer object to customer business object
            var itemTransaction = DataTransferObjectMapper.Voucher.Mapper.FromDataTransferObject(request.ItemTransaction);
            if (request.ItemTransaction != null)
             //   itemTransactionDetails = DataTransferObjectMapper.Voucher.Mapper.FromDataTransferObjects(request.ItemTransaction.ItemTransactionDetails);
            itemTransactionDetails = DataTransferObjectMapper.Voucher.Mapper.FromDataTransferObjects(request.ItemTransactionDetails);

            var obJourentryAccount = new JournalEntryAccount();
            var obJourentryAccountForTax = new JournalEntryAccount(); 
            var obTaxTrans = new TaxTrans();
            IList<JournalEntryAccount> listJournalEntryAccountEntityForTax = new List<JournalEntryAccount>(); 
            IList<JournalEntryAccount> listJournalEntryAccountEntity = new List<JournalEntryAccount>();
            IList<TaxTrans> listTaxTransEntity = new List<TaxTrans>(); 
            IList<AccountBalance> listAccountBalanceEntity = new List<AccountBalance>();
            ItemTransactioCommonFunction cl = new ItemTransactioCommonFunction();
            if (request.ItemTransaction != null)
            {

                listJournalEntryAccountEntityForTax = cl.GetListJournalEntryAccountForTax(request);
                listJournalEntryAccountEntity = cl.GetListJournalEntryAccount(request);
                listTaxTransEntity = cl.GetListTaxTrans(request);
                listAccountBalanceEntity = cl.GetListAccountBalance(request);
            }
            var i = 0;
            var number = 0;
            // Validate customer business rules
            if (request.Action != "Delete")
            {
                if (!itemTransaction.Validate())
                {
                    response.Acknowledge = AcknowledgeType.Failure;

                    foreach (var error in itemTransaction.ValidationErrors)
                        response.Message += error + Environment.NewLine;

                    return response;
                }
            }

            try
            {
                switch (request.Action)
                {
                    case "Create":
                        using (var scope = new TransactionScope())
                        {
                            //insert master
                            itemTransaction.TotalAmountOc = 0;
                            itemTransaction.TotalAmountTax = 0;
                            foreach (var itemTransactionDetail in itemTransactionDetails)
                            {
                                itemTransaction.TotalAmountOc = itemTransaction.TotalAmountOc + itemTransactionDetail.AmountOc;
                                itemTransaction.TotalAmountTax = itemTransaction.TotalAmountTax + itemTransactionDetail.AmountVat;
                            }
                            itemTransaction.RefId = ItemTransactionDao.GetSequence();
                            errorMessage = ItemTransactionDao.InsertItemTransaction(itemTransaction);
                            if (errorMessage != null)
                            {
                                response.Acknowledge = AcknowledgeType.Failure;
                                response.Message = errorMessage;
                                scope.Dispose();
                                return response;
                            }
                            //insert detail
                            foreach (var itemTransactionDetail in itemTransactionDetails)
                            {
                                itemTransactionDetail.ItemTransactionDetailId = ItemTransactionDetailDao.GetSequence();
                                itemTransactionDetail.RefId = itemTransaction.RefId;
                                if (!itemTransactionDetail.Validate())
                                {
                                    response.Acknowledge = AcknowledgeType.Failure;

                                    foreach (var error in itemTransaction.ValidationErrors)
                                        response.Message += error + Environment.NewLine;

                                    return response;
                                }
                                response.Message = ItemTransactionDetailDao.InsertItemTransactionDetail(itemTransactionDetail);
                                if (response.Message != null)
                                {
                                    response.Acknowledge = AcknowledgeType.Failure;
                                    scope.Dispose();
                                    return response;
                                }                                                          
                                //1 dòng details -> 2 obJourentryAccount (VAT) --????                           // insert bang JourentryAccount
                                obJourentryAccount = listJournalEntryAccountEntity[i];
                                obJourentryAccount.RefId = itemTransactionDetail.RefId;
                                obJourentryAccount.RefDetailId = itemTransactionDetail.ItemTransactionDetailId;
                                if (!obJourentryAccount.Validate())
                                {
                                    foreach (string error in obJourentryAccount.ValidationErrors)
                                        response.Message += error + Environment.NewLine;
                                    response.Acknowledge = AcknowledgeType.Failure;
                                    return response;
                                }
                              response.Message = JournalEntryAccountDao.InsertDoubleJournalEntryAccount(obJourentryAccount);
                              if (response.Message != null)
                              {
                                  response.Acknowledge = AcknowledgeType.Failure;
                                  scope.Dispose();
                                  return response;
                              }
                           // insert bang JourentryAccountForTax
                              if (itemTransactionDetail.AccountNumberVat != null)
                              {
                                  obJourentryAccountForTax = listJournalEntryAccountEntityForTax[i - number];
                                  if (obJourentryAccountForTax.AccountNumber != "")
                                  {
                                      obJourentryAccountForTax.RefId = itemTransactionDetail.RefId;
                                      obJourentryAccountForTax.RefDetailId =
                                          itemTransactionDetail.ItemTransactionDetailId;
                                      if (!obJourentryAccountForTax.Validate())
                                      {
                                          foreach (string error in obJourentryAccountForTax.ValidationErrors)
                                              response.Message += error + Environment.NewLine;
                                          response.Acknowledge = AcknowledgeType.Failure;
                                          return response;
                                      }
                                      response.Message =
                                          JournalEntryAccountDao.InsertDoubleJournalEntryAccount(
                                              obJourentryAccountForTax);
                                      if (response.Message != null)
                                      {
                                          response.Acknowledge = AcknowledgeType.Failure;
                                          scope.Dispose();
                                          return response;
                                      }
                                  }
                              }
                              else
                              {
                                  number = number + 1;
                              }
                                // insert bang TaxTrans
                              obTaxTrans = listTaxTransEntity[i];
                              obTaxTrans.RefId = itemTransactionDetail.RefId;
                              obTaxTrans.RefDetailId = itemTransactionDetail.ItemTransactionDetailId;
                              if (!obTaxTrans.Validate())
                              {
                                  foreach (string error in obTaxTrans.ValidationErrors)
                                      response.Message += error + Environment.NewLine;
                                  response.Acknowledge = AcknowledgeType.Failure;
                                  return response;
                              }
                              response.Message = TaxTransDao.InsertDoubleTaxTrans(obTaxTrans);
    // Abort ở đây!!! 
                              if (response.Message != null)
                              {
                                  response.Acknowledge = AcknowledgeType.Failure;
                                  scope.Dispose();
                                  return response;
                              }
                                i = i + 1;

                                //if (errorMessage == null) { continue; }
                                //else { scope.Dispose(); }
                                //response.Acknowledge = AcknowledgeType.Failure;
                                //response.Message = errorMessage;
                                //return response;
                            }

                            // Kiểm tra đã tồn tại trong bảng Account Balance
                            foreach (var accountBe in listAccountBalanceEntity)
                            {
                                var obAccountBe = AccountBalanceDao.GetExitsAccountBalance(accountBe);
                                if (obAccountBe != null)
                                {
                                    // cập nhật bên TK nợ
                                    if (accountBe.MovementCreditAmountOC == 0)
                                    {
                                        obAccountBe.MovementDebitAmountOC = obAccountBe.MovementDebitAmountOC + accountBe.MovementDebitAmountOC;
                                        AccountBalanceDao.UpdateAccountBalance(obAccountBe);
                                    }
                                    else
                                    {
                                        obAccountBe.MovementCreditAmountOC = obAccountBe.MovementCreditAmountOC + accountBe.MovementCreditAmountOC;
                                        AccountBalanceDao.UpdateAccountBalance(obAccountBe);
                                    }
                                }
                                else
                                {
                                  response.Message =  AccountBalanceDao.InsertAccountBalance(accountBe);
                                }
                            }
                            // get autoNumer
                            var autoNumber = AutoNumberDao.GetAutoNumberByRefType(_unitId.AsInt(),itemTransaction.RefTypeId);
                            autoNumber.Value += 1;
                            response.Message = AutoNumberDao.UpdateAutoNumber(autoNumber);
                            if (response.Message != null)
                            {
                                response.Acknowledge = AcknowledgeType.Failure;
                                scope.Dispose();
                                return response;
                            }
                            scope.Complete();
                        }
                        break;
                    case "Update":
                        using (var scope = new TransactionScope())
                        {
                            // Trừ số tiền khi mà update xử lý Bảng cân đối tài khoản////////////////////////////////////
                            listAccountBalanceEntity.Clear();
                            listAccountBalanceEntity = cl.GetListAccountBalanceOlder(itemTransaction.RefId);
                            foreach (var accountBe in listAccountBalanceEntity)
                            {
                                var obAccountBe = AccountBalanceDao.GetExitsAccountBalance(accountBe);
                                if (obAccountBe != null)
                                {
                                    // cập nhật bên TK nợ
                                    if (accountBe.MovementCreditAmountOC == 0)
                                    {
                                       
                                        obAccountBe.MovementDebitAmountOC = obAccountBe.MovementDebitAmountOC - accountBe.MovementDebitAmountOC;
                                     response.Message =   AccountBalanceDao.UpdateAccountBalance(obAccountBe);
                                    }
                                    else
                                    {
                                        
                                        obAccountBe.MovementCreditAmountOC = obAccountBe.MovementCreditAmountOC - obAccountBe.MovementCreditAmountOC;
                                        response.Message = AccountBalanceDao.UpdateAccountBalance(obAccountBe);
                                    }
                                }

                            }
                            // Cập nhật lại dữ liệu vào bảng cân đối tài khoản
                            listAccountBalanceEntity.Clear();
                            listAccountBalanceEntity =cl. GetListAccountBalance(request);
                            foreach (var accountBe in listAccountBalanceEntity)
                            {
                                var ojectAb = AccountBalanceDao.GetExitsAccountBalance(accountBe);
                                if (ojectAb != null)
                                {
                                    // cập nhật bên TK nợ
                                    if (accountBe.MovementCreditAmountOC == 0)
                                    {
                                   
                                        ojectAb.MovementDebitAmountOC = ojectAb.MovementDebitAmountOC + accountBe.MovementDebitAmountOC;
                                        response.Message = AccountBalanceDao.UpdateAccountBalance(ojectAb);
                                    }
                                    else
                                    {
                                      
                                        ojectAb.MovementCreditAmountOC = ojectAb.MovementCreditAmountOC + accountBe.MovementCreditAmountOC;
                                        response.Message = AccountBalanceDao.UpdateAccountBalance(ojectAb);
                                    }
                                }
                                else
                                {
                                    response.Message = AccountBalanceDao.InsertAccountBalance(accountBe);
                                }
                            }
                            // Xóa dữ liệu trống trong bảng Cân đối tài khoản
                            errorMessage =  AccountBalanceDao.DeleteAccountBalance();
                            if (errorMessage != null)
                            {
                                response.Acknowledge = AcknowledgeType.Failure;
                                response.Message = errorMessage;
                                scope.Dispose();
                                return response;
                            }
                            ////////////////////END BANG CAN DOI TAI KHOAN///////////////////////////////////////////////

                            //update master
                            itemTransaction.TotalAmountOc = 0;
                            itemTransaction.TotalAmountTax = 0;
                            foreach (var itemTransactionDetail in itemTransactionDetails)
                            {
                                itemTransaction.TotalAmountOc = itemTransaction.TotalAmountOc + itemTransactionDetail.AmountOc;
                                itemTransaction.TotalAmountTax = itemTransaction.TotalAmountTax + itemTransactionDetail.AmountVat;
                            }
                            errorMessage = ItemTransactionDao.UpdateItemTransaction(itemTransaction);
                            if (errorMessage != null)
                            {
                                response.Acknowledge = AcknowledgeType.Failure;
                                response.Message = errorMessage;
                                scope.Dispose();
                                return response;
                            }
                            //delete detail
                            var itemTransactionDetailsForDelete = ItemTransactionDetailDao.GetItemTransactionDetailsByItemTransaction(itemTransaction.RefId);
                            foreach (var itemTransactionDetail in itemTransactionDetailsForDelete)
                            {
                                errorMessage = ItemTransactionDetailDao.DeleteItemTransactionDetail(itemTransactionDetail);
                                if (errorMessage == null) continue;
                                response.Acknowledge = AcknowledgeType.Failure;
                                response.Message = errorMessage;
                                return response;
                            }
                            //delete obJourentryAccount
                            obJourentryAccount = listJournalEntryAccountEntity[0];
                            errorMessage = JournalEntryAccountDao.DeleteJournalEntryAccount(obJourentryAccount);
                            if (errorMessage != null)
                            {
                                response.Acknowledge = AcknowledgeType.Failure;
                                response.Message = errorMessage;
                                scope.Dispose();
                                return response;
                            }
                            //delete obJourentryAccountForTax
                            obJourentryAccountForTax = listJournalEntryAccountEntityForTax[0];
                            errorMessage = JournalEntryAccountDao.DeleteJournalEntryAccount(obJourentryAccountForTax);
                            if (errorMessage != null)
                            {
                                response.Acknowledge = AcknowledgeType.Failure;
                                response.Message = errorMessage;
                                scope.Dispose();
                                return response;
                            }
                            //delete obTaxTrans
                            obTaxTrans = listTaxTransEntity[0];
                            errorMessage = TaxTransDao.DeleteTaxTrans(obTaxTrans);

                            if (errorMessage != null)
                            {
                                response.Acknowledge = AcknowledgeType.Failure;
                                response.Message = errorMessage;
                                scope.Dispose();
                                return response;
                            }

                            //insert detail
                            foreach (var itemTransactionDetail in itemTransactionDetails)
                            {
                                itemTransactionDetail.ItemTransactionDetailId = ItemTransactionDetailDao.GetSequence();
                                itemTransactionDetail.RefId = itemTransaction.RefId;
                                if (!itemTransactionDetail.Validate())
                                {
                                    response.Acknowledge = AcknowledgeType.Failure;

                                    foreach (var error in itemTransaction.ValidationErrors)
                                        response.Message += error + Environment.NewLine;

                                    return response;
                                }
                                errorMessage = ItemTransactionDetailDao.InsertItemTransactionDetail(itemTransactionDetail);
                                if (errorMessage != null)
                                {
                                    response.Acknowledge = AcknowledgeType.Failure;
                                    response.Message = errorMessage;
                                    scope.Dispose();
                                    return response;
                                }
                                // Insert into JourentryAcocunt
                                obJourentryAccount = listJournalEntryAccountEntity[i];
                                obJourentryAccount.RefId = itemTransactionDetail.RefId;

       //.....                           //get id details lại !!!
                                obJourentryAccount.RefDetailId = itemTransactionDetail.ItemTransactionDetailId;
                                if (!obJourentryAccount.Validate())
                                {
                                    foreach (string error in obJourentryAccount.ValidationErrors)
                                        response.Message += error + Environment.NewLine;
                                    response.Acknowledge = AcknowledgeType.Failure;
                                    return response;
                                }
                                errorMessage =  JournalEntryAccountDao.InsertDoubleJournalEntryAccount(obJourentryAccount);
                                if (errorMessage != null)
                                {
                                    response.Acknowledge = AcknowledgeType.Failure;
                                    response.Message = errorMessage;
                                    scope.Dispose();
                                    return response;
                                }
                                // Insert into JourentryAcocuntForTax
                                if (itemTransactionDetail.AccountNumberVat != null) 
                                {


                                    obJourentryAccountForTax = listJournalEntryAccountEntityForTax[i - number];
                                if (obJourentryAccountForTax.AccountNumber != "")
                                {
                                    obJourentryAccountForTax.RefId = itemTransactionDetail.RefId;

                                    //.....                           //get id details lại !!!
                                    obJourentryAccountForTax.RefDetailId = itemTransactionDetail.ItemTransactionDetailId;
                                    if (!obJourentryAccountForTax.Validate())
                                    {
                                        foreach (string error in obJourentryAccountForTax.ValidationErrors)
                                            response.Message += error + Environment.NewLine;
                                        response.Acknowledge = AcknowledgeType.Failure;
                                        return response;
                                    }
                                    errorMessage =
                                        JournalEntryAccountDao.InsertDoubleJournalEntryAccount(obJourentryAccountForTax);
                                    if (errorMessage != null)
                                    {
                                        response.Acknowledge = AcknowledgeType.Failure;
                                        response.Message = errorMessage;
                                        scope.Dispose();
                                        return response;
                                    }
                                }
                                }
                                else
                                {
                                    number = number + 1;
                                }
                                // Insert into obTaxTrans
                               obTaxTrans = listTaxTransEntity[i];
                               obTaxTrans.RefId = itemTransactionDetail.RefId;

                               //.....                           //get id details lại !!!
                               obTaxTrans.RefDetailId = itemTransactionDetail.ItemTransactionDetailId;
                               if (!obTaxTrans.Validate())
                               {
                                   foreach (string error in obTaxTrans.ValidationErrors)
                                       response.Message += error + Environment.NewLine;
                                   response.Acknowledge = AcknowledgeType.Failure;
                                   return response;
                               }
                               errorMessage = TaxTransDao.InsertDoubleTaxTrans(obTaxTrans);
                               if (errorMessage != null)
                               {
                                   response.Acknowledge = AcknowledgeType.Failure;
                                   response.Message = errorMessage;
                                   scope.Dispose();
                                   return response;
                               }
                                i = i + 1;

                                if (response.Message != null)
                                {
                                    response.Acknowledge = AcknowledgeType.Failure;
                                    scope.Dispose();
                                    return response;
                                }                           
                                
                            }
                            scope.Complete();
                        }
                        break;
                    case "Delete":
                        using (var scope = new TransactionScope())
                        {
                            //delete master & detail
                            var criteria = request.Criteria;
                            var details = ItemTransactionDetailDao.GetItemTransactionDetailsByItemTransaction(criteria.ItemTransactionId);

                            var itemTransactionForDelete = ItemTransactionDao.GetItemTransaction(criteria.ItemTransactionId);
                            errorMessage = ItemTransactionDao.DeleteItemTransaction(itemTransactionForDelete);
                            if (errorMessage != null)
                            {
                                response.Acknowledge = AcknowledgeType.Failure;
                                response.Message = errorMessage;
                                scope.Dispose();
                                return response;
                            }
                            // Xóa bảng JourentryAccount
                            obJourentryAccount.RefId = itemTransactionForDelete.RefId;
                            obJourentryAccount.RefTypeId = itemTransactionForDelete.RefTypeId;
                            obJourentryAccount.RefNo = itemTransactionForDelete.RefNo;
                            errorMessage = JournalEntryAccountDao.DeleteJournalEntryAccount(obJourentryAccount);
                            if (errorMessage != null)
                            {
                                response.Acknowledge = AcknowledgeType.Failure;
                                response.Message = errorMessage;
                                scope.Dispose();
                                return response;
                            }
                            // Xóa bảng JourentryAccountForTax
                            obJourentryAccountForTax.RefId = itemTransactionForDelete.RefId;
                            obJourentryAccountForTax.RefTypeId = itemTransactionForDelete.RefTypeId;
                            obJourentryAccountForTax.RefNo = itemTransactionForDelete.RefNo;
                            errorMessage = JournalEntryAccountDao.DeleteJournalEntryAccount(obJourentryAccountForTax);
                            if (errorMessage != null)
                            {
                                response.Acknowledge = AcknowledgeType.Failure;
                                response.Message = errorMessage;
                                scope.Dispose();
                                return response;
                            }
                            // Xóa bảng TaxTrans
                            obTaxTrans.RefId = itemTransactionForDelete.RefId;
                            obTaxTrans.RefTypeId = itemTransactionForDelete.RefTypeId;
                            obTaxTrans.RefNo = itemTransactionForDelete.RefNo;
                            errorMessage = TaxTransDao.DeleteTaxTrans(obTaxTrans);
                            if (errorMessage != null)
                            {
                                response.Acknowledge = AcknowledgeType.Failure;
                                response.Message = errorMessage;
                                scope.Dispose();
                                return response;
                            }
                            // Cập nhật lại dữ liệu vào bảng cân đối tài khoản
                            listAccountBalanceEntity.Clear();
                            request.ItemTransaction = DataTransferObjectMapper.Voucher.Mapper.ToDataTransferObject( itemTransactionForDelete);
                            request.ItemTransactionDetails =DataTransferObjectMapper.Voucher.Mapper.ToDataTransferObjects(details);
                            listAccountBalanceEntity = cl.GetListAccountBalance(request);
                            foreach (var accountBe in listAccountBalanceEntity)
                            {
                                var ojectAb = AccountBalanceDao.GetExitsAccountBalance(accountBe);
                                if (ojectAb != null)
                                {
                                    // cập nhật bên TK nợ
                                    if (accountBe.MovementCreditAmountOC == 0)
                                    {                                     
                                        ojectAb.MovementDebitAmountOC = ojectAb.MovementDebitAmountOC - accountBe.MovementDebitAmountOC;
                                        response.Message =  AccountBalanceDao.UpdateAccountBalance(ojectAb);
                                    }
                                    else
                                    {
                                        
                                        ojectAb.MovementCreditAmountOC = ojectAb.MovementCreditAmountOC - accountBe.MovementCreditAmountOC;
                                        response.Message =  AccountBalanceDao.UpdateAccountBalance(ojectAb);
                                    }
                                }
                            }
                            // Xóa dữ liệu trống trong bảng Cân đối tài khoản
                            errorMessage = AccountBalanceDao.DeleteAccountBalance();

                            if (errorMessage != null)
                            {
                                response.Acknowledge = AcknowledgeType.Failure;
                                response.Message = errorMessage;
                                scope.Dispose();
                                return response;
                            }
                            if (response.Message != null)
                            {
                                response.Acknowledge = AcknowledgeType.Failure;                            
                                scope.Dispose();
                                return response;
                            }
                            scope.Complete();
                        }                           
                        break;
                }
            }
            catch (Exception ex)
            {
                response.Acknowledge = AcknowledgeType.Failure;
                response.Message = ex.Message;
            }

            return response;
        }
        #endregion

        #region Report

        public ReportListResponse SetReportLists(ReportListRequest request)
        {
            var response = new ReportListResponse(request.RequestId);
            var criteria = request.Criteria;

            if (!ValidRequest(request, response, Validate.All))
                return response;

            if (request.LoadOptions.Contains("ReportLists")) //get list of BudgetSourcesProperty
            {
                if ((OptionType.IsUnit & request.Options) == OptionType.IsUnit) //get by unit & paging || non-paging
                {
                    if ((OptionType.IsPaging & request.Options) == OptionType.IsPaging)
                    {
                        var accounts = ReportListDao.GetPaged(_unitId.AsInt(), request.CurrentPage);
                        var totalPage = ReportListDao.GetPageSize(_unitId.AsInt());
                        response.TotalPage = totalPage;
                        response.ReportLists = DataTransferObjectMapper.Mapper.ToDataTransferObjects(accounts);
                    }
                    else
                    {
                        if (request.LoadOptions.Contains("ForComboTree"))
                        {
                            //var accounts = ReportListDao.GetReportListsForComboTree(_unitId.AsInt());
                            //response.ReportLists = DataTransferObjectMapper.Mapper.ToDataTransferObjects(accounts);
                        }
                        else
                        {
                            //var accounts = ReportListDao.GetReportListsByUnit(_unitId.AsInt());
                            //response.ReportLists = Mapper.ToDataTransferObjects(accounts);
                        }
                    }
                }

            }

            if (request.LoadOptions.Contains("ReportList")) //get budgetSource by id
            {
                var account =
                    ReportListDao.GetReportList(criteria.ReportListId);
                response.ReportList = DataTransferObjectMapper.Mapper.ToDataTransferObject(account);
            }
            if (request.LoadOptions.Contains(("TotalPage")))
            {
                var totalPage = ReportListDao.GetPageSize(_unitId.AsInt());
                response.TotalPage = totalPage;
            }
            return response;
        }

        /// <summary>
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        public ReportListResponse GetReportLists(ReportListRequest request)
        {
            var response = new ReportListResponse(request.RequestId);
            var criteria = request.Criteria;

            if (!ValidRequest(request, response, Validate.All))
                return response;

            if (request.LoadOptions.Contains("ReportLists")) //get list of BudgetSourcesProperty
            {

                var reportLists = ReportListDao.GetReportLists();
                response.ReportLists =
                    DataTransferObjectMapper.Mapper.ToDataTransferObjects(reportLists);
            }

            if (request.LoadOptions.Contains("ReportList")) //get budgetSource by id
            {
                var reportList = ReportListDao.GetReportList(criteria.ReportListId);
                response.ReportList = DataTransferObjectMapper.Mapper.ToDataTransferObject(reportList);
            }
            if (request.LoadOptions.Contains(("TotalPage")))
            {
                var totalPage = ReportListDao.GetPageSize(_unitId.AsInt());
                if (totalPage == 0)
                {
                    totalPage = 1;
                }
                response.TotalPage = totalPage;
            }
            return response;
        }

        /// <summary>
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        public ReportGroupResponse GetReportGroups(ReportGroupRequest request)
        {
            var response = new ReportGroupResponse(request.RequestId);
            var criteria = request.Criteria;

            if (!ValidRequest(request, response, Validate.All))
                return response;

            if (request.LoadOptions != null)
            {
                if (request.LoadOptions.Contains("ReportGroups"))
                {
                    var reportGroups = ReportGroupDao.GetReportGroups();
                    response.ReportGroups =
                        DataTransferObjectMapper.Mapper.ToDataTransferObjects(reportGroups);
                }

                if (request.LoadOptions.Contains("ReportGroup")) //get ReportGroup by id
                {
                    var reportGroup = ReportGroupDao.GetReportGroup(criteria.ReportGroupId);
                    response.ReportGroup =
                        DataTransferObjectMapper.Mapper.ToDataTransferObject(reportGroup);
                }

            }
            return response;
        }

        /// <summary>
        /// ReportGroup
        /// Set (add, update, delete) customer value.
        /// </summary>
        /// <param name="request">ReportGroup request message.</param>
        /// <returns>
        /// ReportGroup response message.
        /// </returns>
        public ReportGroupResponse SetReportGroups(ReportGroupRequest request)
        {
            var response = new ReportGroupResponse(request.RequestId);
            string errorMessage = null;

            // Validate client tag, access token, and user credentials
            if (!ValidRequest(request, response, Validate.All))
                return response;
            if (request.ReportGroup != null)
            {
                //request.ReportGroup.UnitId = _unitId;
                //request.ReportGroup.IsSystem = false;
            }
            var reportGroup = DataTransferObjectMapper.Mapper.FromDataTransferObject(request.ReportGroup);

            // Validate customer business rules
            if (request.Action != "Delete")
            {
                if (!reportGroup.Validate())
                {
                    response.Acknowledge = AcknowledgeType.Failure;

                    foreach (var error in reportGroup.ValidationErrors)
                        response.Message += error + Environment.NewLine;

                    return response;
                }
            }
            try
            {
                switch (request.Action)
                {
                    case "Create":
                        errorMessage = ReportGroupDao.InsertReportGroup(reportGroup);
                        break;
                    case "Update":
                        errorMessage = ReportGroupDao.UpdateReportGroup(reportGroup);
                        break;
                    case "Delete":
                        var criteria = request.Criteria;
                        var employForDelete = ReportGroupDao.GetReportGroup(criteria.ReportGroupId);
                        errorMessage = ReportGroupDao.DeleteReportGroup(employForDelete);
                        break;
                }
                if (errorMessage == null)
                {
                    response.Acknowledge = AcknowledgeType.Success;
                    response.ReportGroup = DataTransferObjectMapper.Mapper.ToDataTransferObject(reportGroup);
                }
                else
                {
                    response.Acknowledge = AcknowledgeType.Failure;
                    response.Message = errorMessage;
                }
            }
            catch (Exception ex)
            {
                response.Acknowledge = AcknowledgeType.Failure;
                response.Message = ex.Message;
            }

            return response;
        }
        public ReportResponse GetReports(ReportRequest request)
        {
            var response = new ReportResponse(request.RequestId);
            if (request.LoadOptions.Contains("Reports")) //get list
            {
                if (request.LoadOptions.Contains("StockBacklog"))
                {
                    var report = ReportListDao.GetReportStockBacklog(request.FromDate,request.ToDate,request.ListStockId);
                    response.StockBacklog = Mapper.ToDataTransferObjects(report);
                }
                else
                {
                    //var report = FixedAssetReportDao.GetFixedAsset02B(request.FixedAssetCategoryID, _unitId.AsInt(), request.FromDate, request.ToDate);
                    //response.FixedAsset02B = Mapper.ToDataTransferObjects(report);
                }
            }
            return response;
        }

        #endregion

        #region Stocks
        public StockResponse GetStocks(StockRequest request)
        {
            var response = new StockResponse(request.RequestId);
            var criteria = request.Criteria;

            if (!ValidRequest(request, response, Validate.All))
                return response;

            if (request.LoadOptions != null)
            {
                if (request.LoadOptions.Contains("Stocks"))
                {
                    if ((OptionType.IsUnit & request.Options) == OptionType.IsUnit)
                    {
                        if ((OptionType.IsPaging & request.Options) == OptionType.IsPaging)
                        {
                            var stocks = StockDao.GetPaged(_unitId.AsInt(), request.CurrentPage);
                            response.Stocks = DataTransferObjectMapper.Mapper.ToDataTransferObjects(stocks);
                        }
                        else
                        {

                            var stocks = StockDao.GetStockByUnit(_unitId.AsInt());
                            response.Stocks = DataTransferObjectMapper.Mapper.ToDataTransferObjects(stocks);
                         
                        }
                    }
                }
                if (request.LoadOptions.Contains("Stock")) //get EmployTest by id
                {
                    var stocks = StockDao.GetStock((int)criteria.StockId);
                    response.Stock = DataTransferObjectMapper.Mapper.ToDataTransferObject(stocks);
                }

                if (request.LoadOptions.Contains(("TotalPage")))
                {
                    var totalPage = StockDao.GetPageSize(_unitId.AsInt());
                    if (totalPage == 0)
                    {
                        totalPage = 1;
                    }
                    response.TotalPage = totalPage;
                }
            }
            return response;
        }
     
        public StockResponse SetStocks(StockRequest request)
        {
            var response = new StockResponse(request.RequestId);
            string errorMessage = null;

            // Validate client tag, access token, and user credentials
            if (!ValidRequest(request, response, Validate.All))
                return response;
            if (request.Stock != null)
            {
                request.Stock.UnitId = _unitId;
                //request.EmployTest.IsSystem = false;
            }
            // Transform customer data transfer object to customer business object
            var stock = DataTransferObjectMapper.Mapper.FromDataTransferObject(request.Stock); 

            // Validate customer business rules
            if (request.Action != "Delete")
            {
                if (!stock.Validate())
                {
                    response.Acknowledge = AcknowledgeType.Failure;

                    foreach (var error in stock.ValidationErrors)
                        response.Message += error + Environment.NewLine;

                    return response;
                }
            }

            try
            {
                switch (request.Action)
                {
                    case "Create":
                        errorMessage = StockDao.InsertStock(stock);
                        break;
                    case "Update":
                        errorMessage = StockDao.UpdateStock(stock);
                        break;
                    case "Delete":
                        var criteria = request.Criteria;
                        var stockForDelete = StockDao.GetStock((int)criteria.StockId);
                        errorMessage = StockDao.DeleteStock(stockForDelete); 
                        break;
                }
                if (errorMessage == null)
                {
                    response.Acknowledge = AcknowledgeType.Success;
                    response.Stock = DataTransferObjectMapper.Mapper.ToDataTransferObject(stock);
                }
                else
                {
                    response.Acknowledge = AcknowledgeType.Failure;
                    response.Message = errorMessage;
                }
            }
            catch (Exception ex)
            {
                response.Acknowledge = AcknowledgeType.Failure;
                response.Message = ex.Message;
            }
            return response;
        }
        #endregion

        #region FixedAssetCategorys
        public FixedAssetCategoryResponse GetFixedAssetCategorys(FixedAssetCategoryRequest request)
        {
            var response = new FixedAssetCategoryResponse(request.RequestId);
            var criteria = request.Criteria;

            if (!ValidRequest(request, response, Validate.All))
                return response;

            if (request.LoadOptions.Contains("FixedAssetCategorys")) //get list of BudgetSourcesProperty
            {
                if ((OptionType.IsUnit & request.Options) == OptionType.IsUnit) //get by unit & paging || non-paging
                {
                    if ((OptionType.IsPaging & request.Options) == OptionType.IsPaging)
                    {
                        var accounts = FixedAssetCategoryDao.GetPaged(_unitId.AsInt(), request.CurrentPage);
                        var totalPage = FixedAssetCategoryDao.GetPageSize(_unitId.AsInt());
                        response.TotalPage = totalPage;
                        response.FixedAssetCategorys = Mapper.ToDataTransferObjects(accounts);
                    }
                    else
                    {
                        if (request.LoadOptions.Contains("ForComboTree"))
                        {
                            var accounts = FixedAssetCategoryDao.GetFixedAssetCategorysForComboTree(_unitId.AsInt());
                            response.FixedAssetCategorys = Mapper.ToDataTransferObjects(accounts);
                        }
                        else
                        {
                            var accounts = FixedAssetCategoryDao.GetFixedAssetCategorysByUnit(_unitId.AsInt());
                            response.FixedAssetCategorys = Mapper.ToDataTransferObjects(accounts);
                        }
                    }
                }

            }

            if (request.LoadOptions.Contains("FixedAssetCategory")) //get budgetSource by id
            {
                var account = FixedAssetCategoryDao.GetFixedAssetCategory(criteria.FixedAssetCategoryId);
                response.FixedAssetCategory = AcountingService.DataTransferObjectMapper.Mapper.ToDataTransferObject(account);
            }
           


            if (request.LoadOptions.Contains(("TotalPage")))
            {
                var totalPage = FixedAssetCategoryDao.GetPageSize(_unitId.AsInt());
                if (totalPage == 0)
                {
                    totalPage = 1;
                }
                response.TotalPage = totalPage;
            }
            return response;
        }

        public FixedAssetCategoryResponse SetFixedAssetCategorys(FixedAssetCategoryRequest request)
        {

            var response = new FixedAssetCategoryResponse(request.RequestId);
            string errorMessage = null;

            // Validate client tag, access token, and user credentials
            if (!ValidRequest(request, response, Validate.All))
                return response;
            if (request.FixedAssetCategory != null)
            {
                request.FixedAssetCategory.UnitId = _unitId;
            }
            // Transform customer data transfer object to customer business object
            var account = AcountingService.DataTransferObjectMapper.Mapper.FromDataTransferObject(request.FixedAssetCategory);

            // Validate customer business rules
            if (request.Action != "Delete")
            {
                if (!account.Validate())
                {
                    response.Acknowledge = AcknowledgeType.Failure;

                    foreach (var error in account.ValidationErrors)
                        response.Message += error + Environment.NewLine;

                    return response;
                }
            }
            try
            {
                switch (request.Action)
                {
                    case "Create":
                        errorMessage = FixedAssetCategoryDao.InsertFixedAssetCategory(account);
                        break;
                    case "Update":
                        errorMessage = FixedAssetCategoryDao.UpdateFixedAssetCategory(account);
                        break;
                    case "Delete":
                        var criteria = request.Criteria;
                        var accountDelete =
                            FixedAssetCategoryDao.GetFixedAssetCategory(criteria.FixedAssetCategoryId);
                        if (accountDelete == null)
                        {
                            response.Acknowledge = AcknowledgeType.Failure;
                            response.Message = "Không thể xóa ! Dữ liệu không còn tồn tại trong hệ thống !";
                            return response;
                        }
                        //check child
                        var child = FixedAssetCategoryDao.GetFixedAssetCategorysByParent(criteria.FixedAssetCategoryId).Count;
                        if (child == 0)
                        {
                            response.Acknowledge = AcknowledgeType.Success;
                            errorMessage =
                                FixedAssetCategoryDao.DeleteFixedAssetCategory(accountDelete);
                        }
                        else
                        {
                            response.Acknowledge = AcknowledgeType.Failure;
                            response.Message = "Không thể xóa ! Nhóm TK đã có TK con !";
                            return response;
                        }
                        break;
                }
                if (errorMessage == null)
                {
                    response.Acknowledge = AcknowledgeType.Success;
                    response.FixedAssetCategory = AcountingService.DataTransferObjectMapper.Mapper.ToDataTransferObject(account);
                }
                else
                {
                    response.Acknowledge = AcknowledgeType.Failure;
                    response.Message = errorMessage;
                }
            }
            catch (Exception ex)
            {
                response.Acknowledge = AcknowledgeType.Failure;
                response.Message = ex.Message;
            }

            return response;
        }
        #endregion

        #region FixedAssets
        public FixedAssetResponse GetFixedAssets(FixedAssetRequest request)
        {
            var response = new FixedAssetResponse(request.RequestId);
            var criteria = request.Criteria;

            if (!ValidRequest(request, response, Validate.All))
                return response;

            if (request.LoadOptions != null)
            {
                if (request.LoadOptions.Contains("FixedAssets"))
                {
                    if ((OptionType.IsUnit & request.Options) == OptionType.IsUnit)
                    {
                        if ((OptionType.IsPaging & request.Options) == OptionType.IsPaging)
                        {
                            var stocks = FixedAssetDao.GetPaged(_unitId.AsInt(), request.CurrentPage);
                            response.FixedAssets = DataTransferObjectMapper.Mapper.ToDataTransferObjects(stocks);
                        }
                        else
                        {
                            if ((OptionType.IsActive & request.Options) == OptionType.IsActive)
                            {
                                //    var employTests = EmployTestDao.GetEmployTestsByUnit(_unitId.AsInt());
                                //    response.EmployTests = Mapper.ToDataTransferObjects(employTests);
                            }
                        }
                    }
                }
                if (request.LoadOptions.Contains("FixedAsset")) //get EmployTest by id
                {
                    var stocks = FixedAssetDao.GetFixedAsset((int)criteria.FixedAssetId);
                    response.FixedAsset = DataTransferObjectMapper.Mapper.ToDataTransferObject(stocks);
                }

                if (request.LoadOptions.Contains(("TotalPage")))
                {
                    var totalPage = FixedAssetDao.GetPageSize(_unitId.AsInt());
                    if (totalPage == 0)
                    {
                        totalPage = 1;
                    }
                    response.TotalPage = totalPage;
                }
            }
            return response;
        }

        public FixedAssetResponse SetFixedAssets(FixedAssetRequest request)
        {
            var response = new FixedAssetResponse(request.RequestId);
            string errorMessage = null;

            // Validate client tag, access token, and user credentials
            if (!ValidRequest(request, response, Validate.All))
                return response;
            if (request.FixedAsset != null)
            {
                request.FixedAsset.UnitId = _unitId;
                //request.EmployTest.IsSystem = false;
            }
            // Transform customer data transfer object to customer business object
            var stock = DataTransferObjectMapper.Mapper.FromDataTransferObject(request.FixedAsset);

            // Validate customer business rules
            if (request.Action != "Delete")
            {
                if (!stock.Validate())
                {
                    response.Acknowledge = AcknowledgeType.Failure;

                    foreach (var error in stock.ValidationErrors)
                        response.Message += error + Environment.NewLine;

                    return response;
                }
            }

            try
            {
                switch (request.Action)
                {
                    case "Create":
                        errorMessage = FixedAssetDao.InsertFixedAsset(stock);
                        break;
                    case "Update":
                        errorMessage = FixedAssetDao.UpdateFixedAsset(stock);
                        break;
                    case "Delete":
                        var criteria = request.Criteria;
                        var stockForDelete = FixedAssetDao.GetFixedAsset((int)criteria.FixedAssetId);
                        errorMessage = FixedAssetDao.DeleteFixedAsset(stockForDelete);
                        break;
                }
                if (errorMessage == null)
                {
                    response.Acknowledge = AcknowledgeType.Success;
                    response.FixedAsset = DataTransferObjectMapper.Mapper.ToDataTransferObject(stock);
                }
                else
                {
                    response.Acknowledge = AcknowledgeType.Failure;
                    response.Message = errorMessage;
                }
            }
            catch (Exception ex)
            {
                response.Acknowledge = AcknowledgeType.Failure;
                response.Message = ex.Message;
            }
            return response;
        }
        #endregion

        #region InventoryItems
        public InventoryItemResponse GetInventoryItems(InventoryItemRequest request)
        {
            var response = new InventoryItemResponse(request.RequestId);
            var criteria = request.Criteria;

            if (!ValidRequest(request, response, Validate.All))
                return response;

            if (request.LoadOptions != null)
            {
                if (request.LoadOptions.Contains("InventoryItems"))
                {
                    if ((OptionType.IsUnit & request.Options) == OptionType.IsUnit)
                    {
                        if ((OptionType.IsPaging & request.Options) == OptionType.IsPaging)
                        {
                            var inventoryItems = InventoryItemDao.GetPaged(_unitId.AsInt(), request.CurrentPage);
                            response.InventoryItems = DataTransferObjectMapper.Mapper.ToDataTransferObjects(inventoryItems);
                        }
                        else
                        {
                            //if ((OptionType.IsActive & request.Options) == OptionType.IsActive)
                            //{
                            var inventoryItems = InventoryItemDao.GetInventoryItemByUnit(_unitId.AsInt());
                            response.InventoryItems = DataTransferObjectMapper.Mapper.ToDataTransferObjects(inventoryItems);
                          //  }
                        }
                    }
                }
                if (request.LoadOptions.Contains("InventoryItem")) //get EmployTest by id
                {
                    var inventoryItem = InventoryItemDao.GetInventoryItem((int)criteria.InventoryItemId);
                    response.InventoryItem = DataTransferObjectMapper.Mapper.ToDataTransferObject(inventoryItem);
                }

                if (request.LoadOptions.Contains(("TotalPage")))
                {
                    var totalPage = InventoryItemDao.GetPageSize(_unitId.AsInt());
                    if (totalPage==0)
                    {
                        totalPage = 1;
                    }
                    response.TotalPage = totalPage;
                }
                //dành cho phần vật tư
                if (request.LoadOptions.Contains("ItemStock"))
                {
                    var inventoryItems = InventoryItemDao.GetInventoryItemListByStock(_unitId.AsInt(),
                                                                                      request.ItemStockId,
                                                                                      request.InventoryItemId,
                                                                                      request.PostDate);
                    response.InventoryItems = DataTransferObjectMapper.Mapper.ToDataTransferObjects(inventoryItems);
                }
            }
            return response;
        }
      
        public InventoryItemResponse SetInventoryItems(InventoryItemRequest request)
        {
            var response = new InventoryItemResponse(request.RequestId);
            string errorMessage = null;

            // Validate client tag, access token, and user credentials
            if (!ValidRequest(request, response, Validate.All))
                return response;
            if (request.InventoryItem != null)
            {
                request.InventoryItem.UnitId = _unitId;
                //request.EmployTest.IsSystem = false;
            }
            // Transform customer data transfer object to customer business object
            var inventoryItem = DataTransferObjectMapper.Mapper.FromDataTransferObject(request.InventoryItem);

            // Validate customer business rules
            if (request.Action != "Delete")
            {
                if (!inventoryItem.Validate())
                {
                    response.Acknowledge = AcknowledgeType.Failure;

                    foreach (var error in inventoryItem.ValidationErrors)
                        response.Message += error + Environment.NewLine;

                    return response;
                }
            }

            try
            {
                switch (request.Action)
                {
                    case "Create":
                        errorMessage = InventoryItemDao.InsertInventoryItem(inventoryItem);
                        break;
                    case "Update":
                        errorMessage = InventoryItemDao.UpdateInventoryItem(inventoryItem);
                        break;
                    case "Delete":
                        var criteria = request.Criteria;
                        var inventoryItemForDelete = InventoryItemDao.GetInventoryItem((int)criteria.InventoryItemId);
                        errorMessage = InventoryItemDao.DeleteInventoryItem(inventoryItemForDelete);
                        break;
                }
                if (errorMessage == null)
                {
                    response.Acknowledge = AcknowledgeType.Success;
                    response.InventoryItem = DataTransferObjectMapper.Mapper.ToDataTransferObject(inventoryItem);
                }
                else
                {
                    response.Acknowledge = AcknowledgeType.Failure;
                    response.Message = errorMessage;
                }
            }
            catch (Exception ex)
            {
                response.Acknowledge = AcknowledgeType.Failure;
                response.Message = ex.Message;
            }
            return response;
        }
        #endregion

        #region DbOptions
        public DbOptionResponse GetDbOptions(DbOptionRequest request)
        {
            var response = new DbOptionResponse(request.RequestId);
            var criteria = request.Criteria;

            if (!ValidRequest(request, response, Validate.All))
                return response;

            if (request.LoadOptions.Contains("DbOptions")) //get list of BudgetSourcesProperty
            {
                if ((OptionType.IsUnit & request.Options) == OptionType.IsUnit) //get by unit & paging || non-paging
                {
                    var dbOptions = DbOptionDao.GetDbOptionsByUnit(_unitId.AsInt());
                    response.DbOptions = DataTransferObjectMapper.Mapper.ToDataTransferObjects(dbOptions);

                }
                else //get all
                {
                //    var dbOptions = DbOptionDao.GetDbOptions();
                //    response.DbOptions = AcountingService.DataTransferObjectMapper.Mapper.ToDataTransferObjects(dbOptions);

                }
            }

            if (request.LoadOptions.Contains("DbOption")) //get budgetSource by id
            {
                var dbOption = DbOptionDao.GetDbOption(criteria.DbOptionId);
                response.DbOption = DataTransferObjectMapper.Mapper.ToDataTransferObject(dbOption);
            }

            return response;
        }

        public DbOptionResponse SetDbOptions(DbOptionRequest request)
        {
            var response = new DbOptionResponse(request.RequestId);

            // Validate client tag, access token, and user credentials
            if (!ValidRequest(request, response, Validate.All))
                return response;
            try
            {
                switch (request.Action)
                {
                    case "Update":
                        foreach (var item in request.DbOptions)
                        {
                            item.UnitId = _unitId;
                            var dbOption = DataTransferObjectMapper.Mapper.FromDataTransferObject(item);
                            if (!dbOption.Validate())
                            {
                                response.Acknowledge = AcknowledgeType.Failure;

                                foreach (var error in dbOption.ValidationErrors)
                                    response.Message += error + Environment.NewLine;

                                return response;
                            }
                            string errorMessage = DbOptionDao.UpdateDbOption(dbOption);
                            if (errorMessage == null) { response.Acknowledge = AcknowledgeType.Success; }
                            else
                            {
                                response.Acknowledge = AcknowledgeType.Failure;
                                response.Message = errorMessage;
                            }
                        }
                        break;
                }
            }
            catch (Exception ex)
            {
                response.Acknowledge = AcknowledgeType.Failure;
                response.Message = ex.Message;
            }

            return response;
        }
        #endregion

        #region AutoBusinesss
        public AutoBusinessResponse GetAutoBusinesss(AutoBusinessRequest request)
        {
            var response = new AutoBusinessResponse(request.RequestId);
            var criteria = request.Criteria;

            if (!ValidRequest(request, response, Validate.All))
                return response;

            if (request.LoadOptions != null)
            {
                if (request.LoadOptions.Contains("AutoBusinesss"))
                {
                    if ((OptionType.IsUnit & request.Options) == OptionType.IsUnit)
                    {
                        if ((OptionType.IsPaging & request.Options) == OptionType.IsPaging)
                        {
                            var autoBusinesss = AutoBusinessDao.GetPaged(_unitId.AsInt(), request.CurrentPage);
                            response.AutoBusinesss = DataTransferObjectMapper.Mapper.ToDataTransferObjects(autoBusinesss);
                        }
                        else
                        {
                            //if ((OptionType.IsActive & request.Options) == OptionType.IsActive)
                            //{
                            var autoBusinesss = AutoBusinessDao.GetAutoBusinessByUnit(_unitId.AsInt());
                            response.AutoBusinesss = Mapper.ToDataTransferObjects(autoBusinesss);
                          //  }
                        }
                    }
                }
                if (request.LoadOptions.Contains("AutoBusiness")) //get EmployTest by id
                {
                    var autoBusinesss = AutoBusinessDao.GetAutoBusiness((int)criteria.AutoBusinessId);
                    response.AutoBusiness = DataTransferObjectMapper.Mapper.ToDataTransferObject(autoBusinesss);
                }

                if (request.LoadOptions.Contains(("TotalPage")))
                {
                    var totalPage = AutoBusinessDao.GetPageSize(_unitId.AsInt());
                    if (totalPage == 0)
                    {
                        totalPage = 1;
                    }
                    response.TotalPage = totalPage;
                }
            }
            return response;
        }

        public AutoBusinessResponse SetAutoBusinesss(AutoBusinessRequest request)
        {
            var response = new AutoBusinessResponse(request.RequestId);
            string errorMessage = null;

            // Validate client tag, access token, and user credentials
            if (!ValidRequest(request, response, Validate.All))
                return response;
            if (request.AutoBusiness != null)
            {
                request.AutoBusiness.UnitId = _unitId;
                //request.EmployTest.IsSystem = false;
            }
            // Transform customer data transfer object to customer business object
            var autoBusiness = DataTransferObjectMapper.Mapper.FromDataTransferObject(request.AutoBusiness);

            // Validate customer business rules
            if (request.Action != "Delete")
            {
                if (!autoBusiness.Validate())
                {
                    response.Acknowledge = AcknowledgeType.Failure;

                    foreach (var error in autoBusiness.ValidationErrors)
                        response.Message += error + Environment.NewLine;

                    return response;
                }
            }

            try
            {
                switch (request.Action)
                {
                    case "Create":
                        errorMessage = AutoBusinessDao.InsertAutoBusiness(autoBusiness);
                        break;
                    case "Update":
                        errorMessage = AutoBusinessDao.UpdateAutoBusiness(autoBusiness);
                        break;
                    case "Delete":
                        var criteria = request.Criteria;
                        var stockForDelete = AutoBusinessDao.GetAutoBusiness((int)criteria.AutoBusinessId);
                        errorMessage = AutoBusinessDao.DeleteAutoBusiness(stockForDelete);
                        break;
                }
                if (errorMessage == null)
                {
                    response.Acknowledge = AcknowledgeType.Success;
                    response.AutoBusiness = DataTransferObjectMapper.Mapper.ToDataTransferObject(autoBusiness);
                }
                else
                {
                    response.Acknowledge = AcknowledgeType.Failure;
                    response.Message = errorMessage;
                }
            }
            catch (Exception ex)
            {
                response.Acknowledge = AcknowledgeType.Failure;
                response.Message = ex.Message;
            }
            return response;
        }
        #endregion

        #region RefTypes
        public RefTypeResponse GetRefTypes(RefTypeRequest request)
        {
            var response = new RefTypeResponse();

            if (request.LoadOptions.Contains("RefTypes"))
            {
                var obj = RefTypeDao.GetRefTypes();
                response.RefTypes = DataTransferObjectMapper.Mapper.ToDataTransferObjects(obj); 
            }

            return response;
        }
#endregion

        #region VoucherTypes
        public VoucherTypeResponse GetVoucherTypes(VoucherTypeRequest request)
        {
            var response = new VoucherTypeResponse();

            if (request.LoadOptions.Contains("VoucherTypes"))
            {
               var obj= request.LoadOptions.Contains("IsActive") ? VoucherTypeDao.GetVoucherTypesByIsActive(true) : VoucherTypeDao.GetVoucherTypes();
                 response.VoucherTypes =DataTransferObjectMapper.Mapper.ToDataTransferObjects(obj); 
            }
            

            return response;
        }

#endregion

        #region Customers
        public CustomerResponse GetCustomers(CustomerRequest request)
        {
            var response = new CustomerResponse(request.RequestId);
            var criteria = request.Criteria;

            if (!ValidRequest(request, response, Validate.All))
                return response;

            if (request.LoadOptions != null)
            {
                if (request.LoadOptions.Contains("Customers"))
                {
                    if ((OptionType.IsUnit & request.Options) == OptionType.IsUnit)
                    {
                        if ((OptionType.IsPaging & request.Options) == OptionType.IsPaging)
                        {
                            var customers = CustomerDao.GetPaged(_unitId.AsInt(), request.CurrentPage);
                            response.Customers = Mapper.ToDataTransferObjects(customers);
                        }
                        else
                        {
                            //if ((OptionType.IsActive & request.Options) == OptionType.IsActive)
                            //{
                                var customers = CustomerDao.GetCustomerByUnit(_unitId.AsInt());
                                response.Customers = Mapper.ToDataTransferObjects(customers);
                           // }
                        }
                    }
                }
                if (request.LoadOptions.Contains("Customer")) //get EmployTest by id
                {
                    var customer = CustomerDao.GetCustomer((int)criteria.CustomerId);
                    response.Customer = Mapper.ToDataTransferObject(customer);
                }

                if (request.LoadOptions.Contains(("TotalPage")))
                {
                    var totalPage = CustomerDao.GetPageSize(_unitId.AsInt());
                    if (totalPage == 0)
                    {
                        totalPage = 1;
                    }
                    response.TotalPage = totalPage;
                }
            }
            return response;
        }

        public CustomerResponse SetCustomers(CustomerRequest request)
        {
            var response = new CustomerResponse(request.RequestId);
            string errorMessage = null;

            // Validate client tag, access token, and user credentials
            if (!ValidRequest(request, response, Validate.All))
                return response;
            if (request.Customer != null)
            {
                request.Customer.UnitId = _unitId;
                //request.EmployTest.IsSystem = false;
            }
            // Transform customer data transfer object to customer business object
            var customer = DataTransferObjectMapper.Mapper.FromDataTransferObject(request.Customer); 

            // Validate customer business rules
            if (request.Action != "Delete")
            {
                if (!customer.Validate())
                {
                    response.Acknowledge = AcknowledgeType.Failure;

                    foreach (var error in customer.ValidationErrors)
                        response.Message += error + Environment.NewLine;

                    return response;
                }
            }

            try
            {
                switch (request.Action)
                {
                    case "Create":
                        errorMessage = CustomerDao.InsertCustomer(customer);
                        break;
                    case "Update":
                        errorMessage = CustomerDao.UpdateCustomer(customer);
                        break;
                    case "Delete":
                        var criteria = request.Criteria;
                        var stockForDelete = CustomerDao.GetCustomer((int)criteria.CustomerId);
                        errorMessage = CustomerDao.DeleteCustomer(stockForDelete);
                        break;
                }
                if (errorMessage == null)
                {
                    response.Acknowledge = AcknowledgeType.Success;
                    response.Customer = DataTransferObjectMapper.Mapper.ToDataTransferObject(customer);
                }
                else
                {
                    response.Acknowledge = AcknowledgeType.Failure;
                    response.Message = errorMessage;
                }
            }
            catch (Exception ex)
            {
                response.Acknowledge = AcknowledgeType.Failure;
                response.Message = ex.Message;
            }
            return response;
        }

        #endregion

        #region Vendors
        public VendorResponse GetVendors(VendorRequest request)
        {
            var response = new VendorResponse(request.RequestId);
            var criteria = request.Criteria;

            if (!ValidRequest(request, response, Validate.All))
                return response;

            if (request.LoadOptions != null)
            {
                if (request.LoadOptions.Contains("Vendors"))
                {
                    if ((OptionType.IsUnit & request.Options) == OptionType.IsUnit)
                    {
                        if ((OptionType.IsPaging & request.Options) == OptionType.IsPaging)
                        {
                            var vendors = VendorDao.GetPaged(_unitId.AsInt(), request.CurrentPage);
                            response.Vendors = DataTransferObjectMapper.Mapper.ToDataTransferObjects(vendors); 
                        }
                        else
                        {
                            //if ((OptionType.IsActive & request.Options) == OptionType.IsActive)
                            //{
                            var vendors = VendorDao.GetVendorByUnit(_unitId.AsInt());
                            response.Vendors = Mapper.ToDataTransferObjects(vendors);
                         //   }
                        }
                    }
                }
                if (request.LoadOptions.Contains("Vendor")) //get EmployTest by id
                {
                    var vendor = VendorDao.GetVendor((int)criteria.VendorId);
                    response.Vendor = DataTransferObjectMapper.Mapper.ToDataTransferObject(vendor);
                }

                if (request.LoadOptions.Contains(("TotalPage")))
                {
                    var totalPage = StockDao.GetPageSize(_unitId.AsInt());
                    if (totalPage == 0)
                    {
                        totalPage = 1;
                    }
                    response.TotalPage = totalPage;
                }
            }
            return response;
        }

        public VendorResponse SetVendors(VendorRequest request)
        {
            var response = new VendorResponse(request.RequestId);
            string errorMessage = null;

            // Validate client tag, access token, and user credentials
            if (!ValidRequest(request, response, Validate.All))
                return response;
            if (request.Vendor != null)
            {
                request.Vendor.UnitId = _unitId;
                //request.EmployTest.IsSystem = false;
            }
            // Transform customer data transfer object to customer business object
            var vendor = DataTransferObjectMapper.Mapper.FromDataTransferObject(request.Vendor);

            // Validate customer business rules
            if (request.Action != "Delete")
            {
                if (!vendor.Validate())
                {
                    response.Acknowledge = AcknowledgeType.Failure;

                    foreach (var error in vendor.ValidationErrors)
                        response.Message += error + Environment.NewLine;

                    return response;
                }
            }

            try
            {
                switch (request.Action)
                {
                    case "Create":
                        errorMessage = VendorDao.InsertVendor(vendor);
                        break;
                    case "Update":
                        errorMessage = VendorDao.UpdateVendor(vendor);
                        break;
                    case "Delete":
                        var criteria = request.Criteria;
                        var stockForDelete = VendorDao.GetVendor((int)criteria.VendorId);
                        errorMessage = VendorDao.DeleteVendor(stockForDelete);
                        break;
                }
                if (errorMessage == null)
                {
                    response.Acknowledge = AcknowledgeType.Success;
                    response.Vendor = DataTransferObjectMapper.Mapper.ToDataTransferObject(vendor);
                }
                else
                {
                    response.Acknowledge = AcknowledgeType.Failure;
                    response.Message = errorMessage;
                }
            }
            catch (Exception ex)
            {
                response.Acknowledge = AcknowledgeType.Failure;
                response.Message = ex.Message;
            }
            return response;
        }
        #endregion

        #region Departments

        public DepartmentResponse GetDepartments(DepartmentRequest request)
        {
            var response = new DepartmentResponse(request.RequestId);
            var criteria = request.Criteria;

            if (!ValidRequest(request, response, Validate.All))
                return response;

            if (request.LoadOptions != null)
            {
                if (request.LoadOptions.Contains("Departments"))
                {
                    if ((OptionType.IsUnit & request.Options) == OptionType.IsUnit)
                    {
                        if ((OptionType.IsPaging & request.Options) == OptionType.IsPaging)
                        {
                            var departments = DepartmentDao.GetPaged(_unitId.AsInt(), request.CurrentPage);
                            response.Departments = DataTransferObjectMapper.Mapper.ToDataTransferObjects(departments);
                        }
                        else
                        {

                            var stocks = DepartmentDao.GetDepartmentByUnit(_unitId.AsInt());
                            response.Departments = DataTransferObjectMapper.Mapper.ToDataTransferObjects(stocks);

                        }
                    }
                }
                if (request.LoadOptions.Contains("Department")) //get EmployTest by id
                {
                    var department = DepartmentDao.GetDepartment((int)criteria.DepartmentId);
                    response.Department = DataTransferObjectMapper.Mapper.ToDataTransferObject(department);
                }

                if (request.LoadOptions.Contains(("TotalPage")))
                {
                    var totalPage = DepartmentDao.GetPageSize(_unitId.AsInt());
                    if (totalPage == 0)
                    {
                        totalPage = 1;
                    }
                    response.TotalPage = totalPage;
                }
            }
            return response;
        }

        public DepartmentResponse SetDepartments(DepartmentRequest request)
        {
            var response = new DepartmentResponse(request.RequestId);
            string errorMessage = null;

            // Validate client tag, access token, and user credentials
            if (!ValidRequest(request, response, Validate.All))
                return response;
            if (request.Department != null)
            {
                request.Department.UnitId = _unitId;
                //request.EmployTest.IsSystem = false;
            }
            // Transform customer data transfer object to customer business object
            var department = DataTransferObjectMapper.Mapper.FromDataTransferObject(request.Department); 

            // Validate customer business rules
            if (request.Action != "Delete")
            {
                if (!department.Validate())
                {
                    response.Acknowledge = AcknowledgeType.Failure;

                    foreach (var error in department.ValidationErrors)
                        response.Message += error + Environment.NewLine;

                    return response;
                }
            }

            try
            {
                switch (request.Action)
                {
                    case "Create":
                        errorMessage = DepartmentDao.InsertDepartment(department);
                        break;
                    case "Update":
                        errorMessage = DepartmentDao.UpdateDepartment(department);
                        break;
                    case "Delete":
                        var criteria = request.Criteria;
                        var stockForDelete = DepartmentDao.GetDepartment((int)criteria.DepartmentId);
                        errorMessage = DepartmentDao.DeleteDepartment(stockForDelete);
                        break;
                }
                if (errorMessage == null)
                {
                    response.Acknowledge = AcknowledgeType.Success;
                    response.Department = DataTransferObjectMapper.Mapper.ToDataTransferObject(department);
                }
                else
                {
                    response.Acknowledge = AcknowledgeType.Failure;
                    response.Message = errorMessage;
                }
            }
            catch (Exception ex)
            {
                response.Acknowledge = AcknowledgeType.Failure;
                response.Message = ex.Message;
            }
            return response;
        }
        #endregion

        public AutoNumberResponse GetAutoNumbers(AutoNumberRequest request)
        {
            var response = new AutoNumberResponse();

            if (request.LoadOptions.Contains("AutoNumber"))
            {
                if (request.LoadOptions.Contains("RefType"))
                {
                    var autoNumber = AutoNumberDao.GetAutoNumberByRefType(_unitId.AsInt(), request.RefTypeId);
                    response.AutoNumber = DataTransferObjectMapper.Mapper.ToDataTransferObject(autoNumber);
                    //   response.AutoNumber = AutoNumberDao.GetAutoNumberByRefType(_unitId.AsInt(), request.RefTypeId);
                }
            }

            return response;
        }
    }
}
